package org.wheel.plugins.toolkit.sql.spi.register;

import org.wheel.plugins.toolkit.sql.helper.FieldMeta;
import org.wheel.plugins.toolkit.sql.plugin.RulePlugin;
import org.wheel.plugins.toolkit.sql.spi.FieldRoleSpi;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 静态注册中心，线程安全，供任意模块使用
 */
public final class FieldRoleRegistry {

    /* column -> role */
    private static final Map<String, String> COLUMN_ROLE_CACHE = new ConcurrentHashMap<>();

    /* 防止重复初始化 */
//    private static volatile boolean initialized = false;

    /* 1. 门闩：以缓存是否为空为准，而不是 boolean 标志 */
    private static boolean isLoaded() {
        return !COLUMN_ROLE_CACHE.isEmpty();
    }

    /* ========== 兜底：懒加载触发器 ========== */
    public static void ensureInitialized() {
        if (!isLoaded()) {                  // 第一次检查（无锁）
            synchronized (FieldRoleRegistry.class) {
                if (!isLoaded()) {          // 第二次检查（加锁）
                    ServiceLoader<FieldRoleSpi> ruleLoader = ServiceLoader.load(FieldRoleSpi.class);
//                    List<FieldRoleSpi> spi =
//                            SpringFactoriesLoader.loadFactories(FieldRoleSpi.class,
//                                    FieldRoleRegistry.class.getClassLoader());
                    List<FieldRoleSpi> spi = new ArrayList<>();
                    ruleLoader.forEach(spi::add);
                    doInit(spi);             // 复用原有逻辑
//                    initialized = true;
                }
            }
        }
    }

    /* 原有初始化入口（供 Spring 主动调用） */
    public static void init(Collection<FieldRoleSpi> spiList) {
        synchronized (FieldRoleRegistry.class) {
            doInit(spiList);
//            initialized = true;
        }
    }

    private static void doInit(Collection<FieldRoleSpi> spiList) {
        spiList.forEach(spi ->
                spi.loadRoles().forEach((role, columns) ->
                        columns.forEach(col ->
                                COLUMN_ROLE_CACHE.put(col.toLowerCase(), role))));
    }

    /**
     * 由 Spring 容器启动时调用，只允许一次
     */
//    public static synchronized void init(Collection<FieldRoleSpi> spiList) {
//        if (initialized) return;
//        for (FieldRoleSpi spi : spiList) {
//            spi.loadRoles().forEach((role, columns) -> {
//                for (String col : columns) {
//                    COLUMN_ROLE_CACHE.putIfAbsent(col.toLowerCase(), role);
//                }
//            });
//        }
//        initialized = true;
//    }

    /**
     * 给 BeanMeta 用的：把存在的字段赋予角色
     */
    public static void assignRoles(Map<String, FieldMeta> fieldMap) {
        ensureInitialized();          // 🔥关键：用到时才触发
        fieldMap.values().forEach(f -> {
            String role = COLUMN_ROLE_CACHE.get(f.getColumn().toLowerCase());
            if (role != null) {
                f.setRole(role);
            }
        });

    }

    /* 工具方法：单元测试用 */
    public static String getRole(String column) {
        ensureInitialized();          // 🔥关键：用到时才触发
        return COLUMN_ROLE_CACHE.get(column.toLowerCase());
    }

    /* 工具方法：非 Spring 环境手动注册 */
    public static void register(String role, Collection<String> columns) {
        ensureInitialized();          // 🔥关键：用到时才触发
        columns.forEach(c -> COLUMN_ROLE_CACHE.put(c.toLowerCase(), role));
    }

    /* 清空，单元测试用 */
    public static void clear() {
        COLUMN_ROLE_CACHE.clear();
//        initialized = false;
    }
}